﻿/**
 * 字符串加密解密
 * **/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.IO.Compression;
using UnityEngine;

public class Common
{
    public const int TPC_PORT = 52315;
    public const int BROADCAST_PORT = 5555;

    /// <summary>
    /// 秒s
    /// </summary>
    /// <param name="l"></param>
    /// <returns></returns>
    public static string GetTimeyyyyMMddBuySecond(long s)
    {
        DateTime targetDt = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1, 0, 0, 0));
        long lTime = long.Parse(s.ToString() + "0000000");
        TimeSpan toNow = new TimeSpan(lTime);
        var tv = targetDt.Add(toNow);
        //return string.Format("{0}年{1}月{2}日{3}:{4}", tv.Year, tv.Month, tv.Day, tv.Hour, tv.Second);
        return tv.ToString("yyyyMMdd");
    }

    public static int GetNowTime_FF()
    {
        DateTime t = DateTime.Now;
        return int.Parse((t.ToString("mmssfff").ToString()));
    }

    /// <summary>
    /// 时间戳,秒
    /// </summary>
    /// <returns></returns>
    public static int GetNowTime()
    {
        int resInt = int.Parse(GetTimeStamp());
        return resInt;
    }

    /// <summary>
    /// 时间戳组装, 秒
    /// </summary>
    /// <returns></returns>
    public static string GetTimeStamp()
    {
        TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
        return Convert.ToInt64(ts.TotalSeconds).ToString();
    }

    /// <summary>
    /// 上一个ticks到现在过去了多少秒
    /// </summary>
    /// <param name="beforTicks">上一个ticks</param>
    /// <returns></returns>
    public static long TickLapseSecond(long beforTicks)
    {
        return ((DateTime.Now.Ticks - beforTicks) / 10000000);
    }

    public static string GetNowTime_Day()
    {
        string sDay = DateTime.Now.ToString("yyyyMMdd");
        return sDay;
    }

    public static string GetNowTime_Hours()
    {
        string sHoure = DateTime.Now.ToString("HH_mm_ss");
        return sHoure;
    }

    public static string GetNowTime2()
    {
        string sDay = DateTime.Now.ToString("yyyyMMddHHmm");
        return sDay;
    }

    public static float GetParticlePlayTime(GameObject obj)
    {
        float ret = 0f;
        var p = obj.GetComponentsInChildren<ParticleSystem>();
        foreach (ParticleSystem ps in p)
        {
            if (ps.enableEmission)
            {
                if (ps.loop)
                {
                    return -1f;
                }
                float dunration = 0f;
                if (ps.emissionRate <= 0)
                {
                    dunration = ps.startDelay + ps.startLifetime;
                }
                else
                {
                    dunration = ps.startDelay + Mathf.Max(ps.duration, ps.startLifetime);
                }
                if (dunration > ret)
                {
                    ret = dunration;
                }
            }
        }

        return ret;
    }
}

public class ENCompress
{
    public static string CompressString(string str)
    {
        var compressBeforeByte = Encoding.GetEncoding("UTF-8").GetBytes(str);
        var compressAfterByte = Compress(compressBeforeByte);
        string compressString = Convert.ToBase64String(compressAfterByte);
        return compressString;
    }

    public static string DecompressString(string str)
    {
        var compressBeforeByte = Convert.FromBase64String(str);
        var compressAfterByte = Decompress(compressBeforeByte);
        string compressString = Encoding.GetEncoding("UTF-8").GetString(compressAfterByte);
        return compressString;
    }

    /// <summary>
    /// Compress
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    private static byte[] Compress(byte[] data)
    {
        try
        {
            var ms = new MemoryStream();
            var zip = new GZipStream(ms, CompressionMode.Compress, true);
            zip.Write(data, 0, data.Length);
            zip.Close();
            var buffer = new byte[ms.Length];
            ms.Position = 0;
            ms.Read(buffer, 0, buffer.Length);
            ms.Close();
            return buffer;

        }
        catch (Exception e)
        {
            throw new Exception(e.Message);
        }
    }

    /// <summary>
    /// Decompress
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    private static byte[] Decompress(byte[] data)
    {
        try
        {
            var ms = new MemoryStream(data);
            var zip = new GZipStream(ms, CompressionMode.Decompress, true);
            var msreader = new MemoryStream();
            var buffer = new byte[0x1000];
            while (true)
            {
                var reader = zip.Read(buffer, 0, buffer.Length);
                if (reader <= 0)
                {
                    break;
                }
                msreader.Write(buffer, 0, reader);
            }
            zip.Close();
            ms.Close();
            msreader.Position = 0;
            buffer = msreader.ToArray();
            msreader.Close();
            return buffer;
        }
        catch (Exception e)
        {
            throw new Exception(e.Message);
        }
    }
}

/// <summary>  
/// DES加密解密算法  
/// </summary>  
public class DES
{
    /// <summary>  
    /// DES加密算法  
    /// sKey为8位或16位  
    /// </summary>  
    /// <param name="pToEncrypt">需要加密的字符串</param>  
    /// <param name="sKey">密钥</param>  
    /// <returns></returns>  
    public string DesEncrypt(string pToEncrypt, string sKey)
    {
        StringBuilder ret = new StringBuilder();

        try
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);
            //des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
            //des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
            var byteKey = ASCIIEncoding.ASCII.GetBytes(sKey);
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(byteKey, byteKey), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();

            foreach (byte b in ms.ToArray())
            {
                ret.AppendFormat("{0:X2}", b);
            }

            ret.ToString();
        }
        catch (System.Exception e)
        {
            Console.WriteLine("加密失败: " + e.Message);
        }
        return ret.ToString();
        //return a;  
    }
    /// <summary>  
    /// DES解密算法  
    /// sKey为8位或16位  
    /// </summary>  
    /// <param name="pToDecrypt">需要解密的字符串</param>  
    /// <param name="sKey">密钥</param>  
    /// <returns></returns>  
    public string DesDecrypt(string pToDecrypt, string sKey)
    {
        MemoryStream ms = new MemoryStream();

        try
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] inputByteArray = new byte[pToDecrypt.Length / 2];
            for (int x = 0; x < pToDecrypt.Length / 2; x++)
            {
                int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));
                inputByteArray[x] = (byte)i;
            }
            //des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
            //des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
            var byteKey = ASCIIEncoding.ASCII.GetBytes(sKey);
            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(byteKey, byteKey), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            StringBuilder ret = new StringBuilder();
        }
        catch
        {
            Console.WriteLine("解密失败");
        }

        return System.Text.Encoding.Default.GetString(ms.ToArray());
    }
}

/// <summary>    
/// 对称加密解密算法类    
/// </summary>    
public class MySymmetricAlgorithm
{
    static MySymmetricAlgorithm instance = null;
    private SymmetricAlgorithm mobjCryptoService;
    //private string Key;
    /// <summary>    
    /// 对称加密类的构造函数    
    /// </summary>    
    public MySymmetricAlgorithm()
    {
        mobjCryptoService = new RijndaelManaged();
        //Key = "Guz(%&hj7x89H$yuBI0456FtmaT5&fvHUFCy76*h%(HilJ$lhj!y6&(*jkP87jH7";
    }

    public static MySymmetricAlgorithm Instance
    {
        get { return instance ?? (instance = new MySymmetricAlgorithm()); }
    }

    /// <summary>    
    /// 获得密钥    
    /// </summary>    
    /// <returns>密钥</returns>    
    private byte[] GetLegalKey(string Key)
    {
        if (Key.Length < 64)
        {
            int count = Key.Length;
            for (int i = count; i < 64; i++)
                Key += "#";
        }

        string sTemp = Key;
        mobjCryptoService.GenerateKey();
        byte[] bytTemp = mobjCryptoService.Key;
        int KeyLength = bytTemp.Length;
        if (sTemp.Length > KeyLength)
            sTemp = sTemp.Substring(0, KeyLength);
        else if (sTemp.Length < KeyLength)
            sTemp = sTemp.PadRight(KeyLength, ' ');
        return ASCIIEncoding.ASCII.GetBytes(sTemp);
    }

    /// <summary>    
    /// 获得初始向量IV    
    /// </summary>    
    /// <returns>初试向量IV</returns>    
    private byte[] GetLegalIV()
    {
        string sTemp = "aclejaspwejgjdjfasrweojksdf$%#@!^!@&#*ajke^!@#jka";     //key 随便写。。  
        mobjCryptoService.GenerateIV();
        byte[] bytTemp = mobjCryptoService.IV;
        int IVLength = bytTemp.Length;
        if (sTemp.Length > IVLength)
            sTemp = sTemp.Substring(0, IVLength);
        else if (sTemp.Length < IVLength)
            sTemp = sTemp.PadRight(IVLength, ' ');
        return ASCIIEncoding.ASCII.GetBytes(sTemp);
    }
    /// <summary>    
    /// 加密方法    
    /// </summary>    
    /// <param name="Source">待加密的串</param>    
    /// <returns>经过加密的串</returns>    
    public string Encrypto(string Source, string strKey)
    {
        byte[] bytIn = UTF8Encoding.UTF8.GetBytes(Source);
        MemoryStream ms = new MemoryStream();
        mobjCryptoService.Key = GetLegalKey(strKey);
        mobjCryptoService.IV = GetLegalIV();
        ICryptoTransform encrypto = mobjCryptoService.CreateEncryptor();
        CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Write);
        cs.Write(bytIn, 0, bytIn.Length);
        cs.FlushFinalBlock();
        ms.Close();
        byte[] bytOut = ms.ToArray();
        return Convert.ToBase64String(bytOut);
    }
    /// <summary>    
    /// 解密方法    
    /// </summary>    
    /// <param name="Source">待解密的串</param>    
    /// <returns>经过解密的串</returns>    
    public string Decrypto(string Source, string strKey)
    {
        byte[] bytIn = Convert.FromBase64String(Source);
        MemoryStream ms = new MemoryStream(bytIn, 0, bytIn.Length);
        mobjCryptoService.Key = GetLegalKey(strKey);
        mobjCryptoService.IV = GetLegalIV();
        ICryptoTransform encrypto = mobjCryptoService.CreateDecryptor();
        CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Read);
        StreamReader sr = new StreamReader(cs);

        string ret = string.Empty;
        try
        {
            ret = sr.ReadToEnd();
        }
        catch (System.Exception e)
        {
            Console.WriteLine("解密失败: " + e.Message);
        }

        return ret;
    }

    #region 异或加密
    /// <summary>
    /// 加密
    /// </summary>
    /// <param name="content"></param>
    /// <param name="secretKey"></param>
    /// <returns></returns>
    public static char[] TextEncrypt(string content, string secretKey)
    {

        char[] data = content.ToCharArray();

        char[] key = secretKey.ToCharArray();
        for (int i = 0; i < data.Length; i++)

        {

            data[i] ^= key[i % key.Length];

        }
        return data;
    }

    /// <summary>
    /// 解密
    /// </summary>
    /// <param name="data"></param>
    /// <param name="secretKey"></param>
    /// <returns></returns>
    public static string TextDecrypt(char[] data, string secretKey)
    {
        char[] key = secretKey.ToCharArray();
        for (int i = 0; i < data.Length; i++)

        {

            data[i] ^= key[i % key.Length];

        }
        return new string(data);
    }
    #endregion
}

public class StaticClass
{
    #region 加密解密
    public static DES dd = new DES();
    // 只支持8位长度的密码
    //public static string StringKey = "Feafan0."; // 加密密钥  

    /// <summary>  
    /// 解密  
    /// </summary>  
    /// <param name="str"></param>  
    /// <returns></returns>  
    public static string StringDecder(string str, string StringKey)
    {
        if (StringKey.Length < 8)
        {
            int count = StringKey.Length;
            for (int i = count; i < 8; i++)
            {
                StringKey += "*";
            }
        }
        else if (StringKey.Length > 8)
            StringKey = StringKey.Substring(0, 8);
        return dd.DesDecrypt(str, StringKey);
    }

    /// <summary>  
    /// 加密  
    /// </summary>  
    /// <param name="str"></param>  
    /// <returns></returns>  
    public static string StringEncoder(string str, string StringKey)
    {
        if (StringKey.Length < 8)
        {
            int count = StringKey.Length;
            for (int i = count; i < 8; i++)
            {
                StringKey += "*";
            }
        }
        else if (StringKey.Length > 8)
            StringKey = StringKey.Substring(0, 8);

        return dd.DesEncrypt(str, StringKey);
    }
    #endregion
}